//#region File Description
/////////////////////////////////////////////////////////////////////////////////////////////////////
//// SerialPort.cs - Serial Port node
////
//// Copyright (C) Javier Valcarce. BSD License
/////////////////////////////////////////////////////////////////////////////////////////////////////
//#endregion

//#region Using Statements
//using System;
//using System.IO.Ports;
//using System.Diagnostics;
//using Dff;
//#endregion


//namespace Arq
//{
//    /// <summary>
//    /// This class represent a serial port device, all data sent to PortI in relayed to serial 
//    /// port, all data sent to serial port is relayed to PortO.
//    /// </summary>
//    public class TtyPort : Node
//    {
//        #region Private members
//        const int IndexPortI = 0;
//        const int IndexPortO = 1;
//        public readonly Port<byte> PortI;
//        public readonly Port<byte> PortO;        
        
//        // serial port object
//        SerialPort ttys0;

//        // maximun amount of data transfered in each execution of relay methods RelayTty2Port() and 
//        // RelayTty2Port()
//        const int MaxChunkSize = 32;

//        // buffer used to transfer that data
//        byte[] data;
//        #endregion

//        #region Contructors
//        /// <summary>
//        /// Constructor
//        /// </summary>
//        /// <param name="tty">TTY device name (e.g. COM1, /dev/tty1, etc)</param>
//        /// <param name="baudrate">Serial port baud rate (e.g. 19200)</param>
//        public TtyPort(string ttyname, int baudrate) 
//            : base ("TtyPort")
//        {           
//            // create ports
//            PortI = new Port<byte>(PortType.I, IndexPortO, Dispatcher);
//            PortO = new Port<byte>(PortType.O, IndexPortI, Dispatcher);

//            PortI.EdgeChange += new DispatcherDelegate(RelayPort2Tty);
//            PortO.EdgeChange += new DispatcherDelegate(RelayTty2Port);

//            data = new byte[MaxChunkSize];
            
//            // create a serial port object and setup it with standart configuration: BaudRate-8N1
//            ttys0 = new SerialPort(ttyname);
//            //
//            ttys0.BaudRate     = baudrate;
//            ttys0.DataBits     = 8;
//            ttys0.Parity       = Parity.None;
//            ttys0.StopBits     = StopBits.One;
//            ttys0.Handshake    = Handshake.None;
//            ttys0.ReadTimeout  = SerialPort.InfiniteTimeout;
//            ttys0.WriteTimeout = SerialPort.InfiniteTimeout;
//            ttys0.Open();

//            // event handler for new data received
//            ttys0.DataReceived += delegate(object sender, SerialDataReceivedEventArgs e) {
//                Dispatcher.BeginInvoke(new DispatcherDelegate(RelayTty2Port));
//            };          
//        }
//        #endregion
        
//        #region Event Handlers 
//        // Data Relay TTY --> PortO
//        void RelayTty2Port(object arg)
//        {
//            if (!PortO.Connected)
//                return;

//            int avail = Math.Min(ttys0.BytesToRead, PortO.Space);
//            int chunk = Math.Min(avail,             MaxChunkSize);

//            if (chunk > 0)
//            {
//                ttys0.Read   (data, 0, chunk);
//                PortO.Enqueue(data, 0, chunk);
//            }

//            if (avail > chunk)
//                Dispatcher.BeginInvoke(RelayTty2Port);
//        }

//        // Data Relay PortI --> TTY
//        void RelayPort2Tty(object arg)
//        {
//            if (!PortI.Connected)
//                return;

//            // Warning: Unfortunately we don't have any mechanism to know when the TX buffer 
//            // has free space, so we call sync API Write() whilst there is data available in
//            // PortI

//            // MaxChunkSize control the suspend time this event handler
//            // aprox. 8*MaxChunkSize/BaudRate
//            int chunk = Math.Min(PortI.Count, MaxChunkSize);

//            if (chunk > 0)
//            {
//                PortI.Dequeue(data, 0, chunk);
//                ttys0.Write  (data, 0, chunk);//block
//            }

//            if (PortI.Count > 0)
//                Dispatcher.BeginInvoke(RelayPort2Tty);
//        }
//        #endregion        
//    }
//}